import { ObjectDirective } from "vue";
const inRange = (v: number, arr: number[]) => {
  return arr[0] <= v && arr[1] >= v;
};
const directive: ObjectDirective = {
  mounted(el, binding) {
    const dragBox = el.parentNode;
    const inner = el;
    let maxW = 0;
    let maxH = 0;
    let minW = dragBox.clientWidth - inner.clientWidth;
    let minH = dragBox.clientHeight - inner.clientHeight;
    // 横纵坐标范围
    let wRange = [minW, maxW];
    let hRange = [minH, maxH];
    let scale = 1;
    let scaleRange: string | null = null;
    // 缩放时需要重新初始化
    const init = () => {
      minW = dragBox.clientWidth - inner.clientWidth - ((scale - 1) * inner.clientWidth) / 2;
      minH =
        dragBox.clientHeight - scale * inner.clientHeight + ((scale - 1) * inner.clientHeight) / 2;
      maxW = ((scale - 1) * inner.clientWidth) / 2;
      maxH = ((scale - 1) * inner.clientHeight) / 2;
      wRange = [minW, maxW];
      hRange = [minH, maxH];
    };
    // 边界限制与返回位置
    const edgeLimit = () => {
      if (inner.offsetLeft < minW) {
        inner.style.left = minW + "px";
      }
      if (inner.offsetLeft > maxW) {
        inner.style.left = maxW + "px";
      }
      if (inner.offsetTop < minH) {
        inner.style.top = minH + "px";
      }
      if (inner.offsetTop > maxH) {
        inner.style.top = maxH + "px";
      }
      binding.value &&
        binding.value({
          x: inner.offsetLeft,
          y: inner.offsetTop,
        });
    };
    edgeLimit();
    // scale与定位恢复
    el.rstScale = (position: any) => {
      scale = 1;
      inner.style.transform = `scale(${scale})`;
      init();
      const x = dragBox.clientWidth / 2 - position.x;
      const y = dragBox.clientHeight / 2 - position.y;
      inner.style.left = x + "px";
      inner.style.top = y + "px";
      edgeLimit();
    };
    dragBox.onmousedown = (e: any) => {
      // 点击时坐标
      let pointFist = [e.pageX, e.pageY];
      dragBox.onmousemove = (e: any) => {
        // 移动坐标
        const pointTemp = [e.pageX, e.pageY];
        // 移动差值
        const diff = [pointTemp[0] - pointFist[0], pointTemp[1] - pointFist[1]];
        const moveLeft = inner.offsetLeft + diff[0];
        const moveTop = inner.offsetTop + diff[1];
        // 判断是否在范围内
        if (inRange(moveLeft, wRange)) {
          inner.style.left = inner.offsetLeft + diff[0] + "px";
        }
        if (inRange(moveTop, hRange)) {
          inner.style.top = inner.offsetTop + diff[1] + "px";
        }
        // 更新坐标
        pointFist = pointTemp;
        binding.value && binding.value({ x: inner.offsetLeft, y: inner.offsetTop });
      };
    };
    dragBox.onmouseup = () => {
      dragBox.onmousemove = null;
    };
    dragBox.onmouseleave = () => {
      dragBox.onmousemove = null;
    };
    // 输出坐标
    inner.onmousedown = (e: any) => {
      console.log(e.offsetX, e.offsetY);
    };
    // 滚轮放大缩小地图，需要改变scale和scale原心,边界限制太难控制，暂时不做原心改变 目前原心在中心，
    scaleRange = inner.getAttribute("scaleRange");
    if (scaleRange) {
      const range = scaleRange.split(",");
      inner.onmousewheel = (e: any) => {
        if (e.wheelDelta < 0) {
          // 缩小
          if (scale <= +range[0]) return;
          scale = Math.round((scale - 0.1) * 10) / 10;
          inner.style.transform = `scale(${scale})`;
        } else {
          // 放大
          if (scale >= +range[1]) return;
          scale = Math.round((scale + 0.1) * 10) / 10;
          inner.style.transform = `scale(${scale})`;
        }
        // inner.style.transformOrigin = `${e.offsetX}px ${e.offsetY}px`;
        init();
        edgeLimit();
      };
    }
  },
};

export default directive;
